home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Collections: Taifun
/
Taifun 148 (1990-08-15)(Ossowski, Stefan)(DE)(PD).zip
/
Taifun 148 (1990-08-15)(Ossowski, Stefan)(DE)(PD).adf
/
Source
/
PenteCalc.s
< prev
next >
Wrap
Text File
|
1990-08-07
|
44KB
|
2,382 lines
;***********************************
;* *
;* PENTE *
;* *
;* implemented by *
;* Tis Veugen *
;* NL-Waalre,1988 *
;* *
;* Amiga 500 *
;* file Pente:PenteCalc.s *
;* *
;***********************************
;
code
bra INITCALC
data
;
RBRDR = 2 ; reduction border
BRDR = 3 ; evaluation border
BXDIM = 19
BYDIM = 19
BXMAX = BRDR + BXDIM + BRDR
BYMAX = BRDR + BYDIM + BRDR
BSIZE = BXMAX * BYMAX
EXMAX = BRDR + 1 + BRDR
EYMAX = BRDR + 1 + BRDR
ESIZE = EXMAX * EYMAX
rdcsq = -1
brdrsq= -[2*BRDR]
empsq = 0
white = $30
black = $34
whbl = white!black ; white OR black
NOMV = -1
KPLY = 16 ; number of plies per move-generation
NPLY = 128 ; number of plies per game
KMOVS = BXDIM*BYDIM ; number of moves per position
NMOVS = KPLY*KMOVS/2 ; total number of moves/2
TableCLEN = $10000
TableEVLEN = $20000
TableLEN = TableCLEN + TableEVLEN
TakeBit = 9 ; Evaluation taken stones = 2^TakeBit
ZCEVI = -$7800
ZAEVI = ZCEVI
ZBEVI = -ZAEVI
ZWIN = $5800
ZBEV = $0001
; History
HcolME = 0
HcolOP = HcolME + 2
HWEVBRD= HcolOP + 2
HBEVBRD= HWEVBRD + 4
HTGMV = HBEVBRD + 4
HPLYNR = HTGMV + 4
HWIN = HPLYNR + 2
HWMEV = HWIN + 2
HBMEV = HWMEV + 1
HPEV = HBMEV + 1
HAEV = HPEV + 2
HBEV = HAEV + 2
HCEV = HBEV + 2
HMV0 = HCEV + 2
HMV1 = HMV0 + 4
HMV2 = HMV1 + 4
HTQS = HMV2 + 4
HRCP = HTQS + 1 + 1
; this part only for game-history
HSBRD = HRCP + 4
HPEV0 = HSBRD + 4
HPEV1 = HPEV0 + 2
LHST = HPEV1 + 2
;
; Move
MPEV0 = 0
MPEV = 2
MSQ = 4
MTK = 6
MMEV = 7
LMOV = 8
MTQS = 2
;
; PSN
PXA = 0 ; help-array
PYA = PXA + BXMAX ; help-array
PXMAX = PYA + BXMAX
PYMAX = PXMAX + 4
PXDIM = PYMAX + 4
PYDIM = PXDIM + 2
PXLO1 = PYDIM + 2
PYLO1 = PXLO1 + 2
PXHI1 = PYLO1 + 2
PYHI1 = PXHI1 + 2
RXLO = PYHI1 + 2
RXLO1 = RXLO + 2
RXLO2 = RXLO1 + 2
RYLO = RXLO2 + 2
RYLO1 = RYLO + 2
RYLO2 = RYLO1 + 2
RXHI = RYLO2 + 2
RXHI1 = RXHI + 2
RXHI2 = RXHI1 + 2
RYHI = RXHI2 + 2
RYHI1 = RYHI + 2
RYHI2 = RYHI1 + 2
RXDIM = RYHI2 + 2
RYDIM = RXDIM + 2
REBRD = RYDIM + 2
PRDC = REBRD + 2
PROW = PRDC + 2
PCOL = PROW + 2
PMEV = PCOL + 2
PPLYCNT = PMEV + 2
PGMVS = PPLYCNT + 2 ; Pointer to moves to be generated (A6)
PMEVLIM = PGMVS + 4 ; Limit number taken pairs of stones
PMVAL = PMEVLIM + 2 ; (positional) Evaluation of taken stone
PESC = PMVAL + 2 ; escape Evaluation
PTQS = PESC + 2 ; allowed QS-code
PIQS = PTQS + 2 ; integral QS-code
PMTQS = PIQS + 2 ; previous move's QS-code
PREGS = PMTQS + 2 ; all registers at start-up
PREG0 = PREGS + 64 ; cleared data
PEVPAT = PREG0 + 32 ; Pev pattern
RWEVBRD = PEVPAT + ESIZE + 1 ; Pointer reduced Pev board white
RBEVBRD = RWEVBRD + 4 ; Pointer reduced Pev board black
WHEVBRD = RBEVBRD + 4 ; Pev board white
BLEVBRD = WHEVBRD + BSIZE ; Pev board black
RPBRD = BLEVBRD + BSIZE ; Pointer reduced Pev board white
PBRD = RPBRD + 4 ; position board
PTableC = PBRD + BSIZE + 1 ; table of Codes
PTableEV= PTableC + 4 ; table of Evaluations
PHST = PTableEV + 4 ; A4
PMVS = PHST + [ NPLY * LHST ]
PTable = PMVS + [ NMOVS * LMOV ]
LPSN = PTable + TableLEN
;
; bit patterns :
;
PATempty = %00
PATwhite = %01
PATblack = %10
PATborder = %11
;
; codes :
;
EVC5 = %10000000 ; pente
EVCn = %01000000 ; normal move
EVC5t = %00100000 ; pente threat
EVC5s = %00010000 ; pente threat solved
EVCtkt = %00001000 ; take threat
EVCtks = %00000100 ; take threat solved
EVCtkl = %00000010 ; take left
EVCtkr = %00000001 ; take right
EVCs5t = %10010011 ; mask for solving pente threat
EVCrds = %10110011 ; mask for reduced moves (no take solve)
EVCrdt = %10110111 ; mask for reduced moves (no take threat)
EVCrdn = %10111111 ; mask for reduced moves (no normal)
EVCall = %11111111 ; mask for all moves
EVCQSI = %00101000 ; mask for QS initialization
;
EVCbit5s = 4 ; bit 4 indicates pente solve
EVCbit5t = 5 ; bit 5 indicates pente threat
EVCbitn = 6 ; bit 6 indicates normal move
;
JEVesc = 4
JEVs5t = 8
JEVrds = 12
JEVrdt = 16
JEVrdn = 20
JEVall = 24
JQSesc = 28
JQSs5t = 32
JQSrds = 36
JQSrdt = 40
JQSrdn = 44
JQSall = 48
JEVQSmax = 52
;
code
;
DIRS: dc.w 1,BXMAX+1,BXMAX,BXMAX-1,-1,-BXMAX-1,-BXMAX,-BXMAX+1,0
;
DPEVPAT:
dc.b 3, 1, 2, 4, 2, 1, 3
dc.b 1, 7, 5, 8, 5, 7, 1
dc.b 2, 5, 1, 1, 1, 5, 2
dc.b 4, 8, 1, 0, 1, 8, 4
dc.b 2, 5, 1, 1, 1, 5, 2
dc.b 1, 7, 5, 8, 5, 7, 1
dc.b 3, 1, 2, 4, 2, 1, 3
;
ZRCPcode:
dc.b JEVall,JQSrdn,JQSrdt,JQSrds
dc.b JQSrds,JQSrds,JQSrds,JQSrds
dc.b JQSrds,JQSrds,JQSrds,JQSrds
dc.b JQSrds,JQSrds,0,0
even
ZRCPSR:
dc.l ZEVesc
dc.l ZEVesc, ZEV, ZEV, ZEV, ZEV, ZEV
dc.l ZQSesc, ZQS, ZQS, ZQS, ZQS, ZQS
dc.l EVCall ; offset=JEVQSmax
dc.l EVCall, EVCs5t, EVCrds, EVCrdt, EVCrdn, EVCall
dc.l EVCall, EVCs5t, EVCrds, EVCrdt, EVCrdn, EVCall
;
RCPescape: ; subroutine for escape,
; to be called by high-level program
lea MIRQPort(PC),A0 ; read message
move.l ExecBase,A6
jsr GetMsg(A6)
move.l D0,-(SP)
;
moveq #0,D1 ; clear MIRQ-signal
lea TM_sigBit(PC),A0
move.b (A0),D0
bset D0,D1
moveq #0,D0
move.l ExecBase,A6
jsr SetSignal(A6)
;
move.l (SP)+,A1
cmpi.w #CMD_Escape,QIcmd(A1)
bne.s RCPstrategy
lea RCPMIRQesc(PC),A0
move.l (A0),D0 ; D0=address(ZEVesc)
lea RCPMIRQA4(PC),A0
move.l (A0),A0 ; A0 points to A4-0
RCPescL:
move.l D0,HRCP(A0)
lea LHST(A0),A0
tst.l HRCP(A0)
bne.s RCPescL
rts
;
RCPstrategy:
cmpi.w #CMD_Strategy,QIcmd(A1)
bne.s RCPerror
move.l QIstrat(A1),A0
lea ZRCPcode(PC),A2
RCPstratL:
move.w (A0)+,D0
move.b D0,(A2)+
bne.s RCPstratL
RCPerror:
rts
;
RCPMIRQA4:
dc.l 0 ; used as store for A4-0
RCPMIRQesc:
dc.l 0 ; used as store for ZEVesc
;
data
QLmsg = 20
Qcmd = QLmsg
Qstatus = Qcmd + 2
Qmovenr = Qstatus + 2
Qrow = Qmovenr + 2
Qcol = Qrow + 2
Qtakes = Qcol + 2
QmevPL = Qtakes + 2
QmevAM = QmevPL + 2
Qresult = QmevAM + 2
QIcmd = QLmsg
QIstrat = QIcmd + 2
IPROG = 4 ; cmd's
IGAME = 8
DOMV = 12
CAMV = 16
EPROG = 20
ECALC = 24
CMD_Escape = 4
CMD_Strategy = 8
RESULT_OK = 0
RESULT_WIN = 1
status_OK = 0
status_ERROR = 1
NT_INTERRUPT = 2
NT_MSGPORT = 4
PA_SIGNAL = 0
PA_SOFTINT = 1
MEMF_CLEAR = $10000
MODE_OLD = 1005
MODE_NEW = 1006
ExecBase = 4
OpenLib = -552
CloseLib = -414
Open = -30
Close = -36
Read = -42
Write = -48
Output = -60
Execute = -222
AllocMem = -198
FreeMem = -210
FindTask = -294
SetSignal = -306
AllocSignal = -330
FreeSignal = -336
AddPort = -354
RemPort = -360
PutMsg = -366
GetMsg = -372
ReplyMsg = -378
WaitPort = -384
FindPort = -390
code
;
MsgPTR: dc.l 0
;
PC_name:
dc.b "PenteCalc",0
even
PM_name:
dc.b "PenteMIRQ",0
even
INITCALC:
lea PC_name(PC),A1
move.l ExecBase,A6
jsr FindPort(A6)
tst.l D0
bne ENDCALCSGNL
;
moveq #-1,D0 ; Port Signal
move.l ExecBase,A6
jsr AllocSignal(A6)
lea TC_sigBit(PC),A0
move.b D0,(A0)
cmpi.b #-1,D0
beq ENDCALCSGNL
;
suba.l A1,A1
move.l ExecBase,A6
jsr FindTask(A6)
lea TC_SigTask(PC),A0
move.l D0,(A0)
;
lea CalcPort(PC),A1
move.l ExecBase,A6
jsr AddPort(A6)
;
INITMIRQ:
lea RCPescape(PC),A0
lea TMi_Code(PC),A1
move.l A0,(A1)
;
lea PM_name(PC),A1
move.l ExecBase,A6
jsr FindPort(A6)
tst.l D0
bne ENDMIRQSGNL
;
moveq #-1,D0 ; Port Signal
move.l ExecBase,A6
jsr AllocSignal(A6)
lea TM_sigBit(PC),A0
move.b D0,(A0)
cmpi.b #-1,D0
beq ENDMIRQSGNL
;
lea MIRQinterrupt(PC),A0
lea TM_SigTask(PC),A1
move.l A0,(A1)
;
lea MIRQPort(PC),A1
move.l ExecBase,A6
jsr AddPort(A6)
;
lea QSst(PC),A0
clr.w (A0)
;
MAINL: move.l A6,-(SP)
lea CalcPort(PC),A0
move.l ExecBase,A6
jsr WaitPort(A6)
;
lea CalcPort(PC),A0
move.l ExecBase,A6
jsr GetMsg(A6)
lea MsgPTR(PC),A0
move.l D0,(A0)
move.l (SP)+,A6
;
move.l D0,A0
move.w Qcmd(A0),D0
cmpi.w #ECALC,D0
beq.s QSECALC
;
lea QSUBS(PC),A1
move.l 0(A1,D0.w),A1
jsr (A1)
;
bra.s MAINL
;
GETMSGPTR: macro
lea MsgPTR(PC),A0
move.l (A0),A1
endm
;
QSECALC:
moveq #status_ERROR,D0
lea QSst(PC),A0
tst.w (A0)
bne.s ENDCALCERR
GETMSGPTR
move.w #status_OK,Qstatus(A1)
move.l ExecBase,A6
jsr ReplyMsg(A6)
ENDCALC:
bsr SUBENDCALC
ENDMIRQSGNL:
bsr SUBENDMIRQ
ENDCALCSGNL:
moveq #0,D0
ENDCALCERR:
rts
;
SUBENDCALC:
lea CalcPort(PC),A1
move.l ExecBase,A6
jsr RemPort(A6)
;
SUBENDCALCPORT:
lea TC_sigBit(PC),A0
move.b (A0),D0
move.l ExecBase,A6
jsr FreeSignal(A6)
rts
;
SUBENDMIRQ:
lea MIRQPort(PC),A1
move.l ExecBase,A6
jsr RemPort(A6)
;
SUBENDMIRQPORT:
lea TM_sigBit(PC),A0
move.b (A0),D0
move.l ExecBase,A6
jsr FreeSignal(A6)
rts
;
QSUBS: dc.l 0,QSIPROG,QSIGAME,QSDOMV,QSCAMV,QSEPROG,QSECALC
QSst: dc.w 0
;
QSIPROG:
moveq #status_ERROR,D0
lea QSst(PC),A0
tst.w (A0)
bne.s QSREPLYs
bsr INITPROG
cmpi.w #status_OK,D0
bne.s QSREPLYs
lea QSst(PC),A0
move.w #1,(A0)
QSREPLYs:
GETMSGPTR
move.w D0,Qstatus(A1)
;
QSREPLY:
move.l A6,-(SP)
move.l ExecBase,A6
jsr ReplyMsg(A6)
move.l (SP)+,A6
rts
;
CKQSst: macro
moveq #status_ERROR,D0
lea QSst(PC),A0
tst.w (A0)
beq.s QSREPLYs
endm
;
QSEPROG:
CKQSst
bsr ENDPROG
cmpi.w #status_OK,D0
bne.s QSREPLYs
lea QSst(PC),A0
clr.w (A0)
bra.s QSREPLYs
;
QSIGAME:
CKQSst
bsr INITGAME
bra.s QSREPLYs
;
QSDOMV: CKQSst
bsr CHECKMOVENR
bne.s QSRTMV ; error!
GETMSGPTR
move.w Qrow(A1),PROW(A3)
move.w Qcol(A1),PCOL(A3)
bsr DOEMOVE
move.l HMV0(A4),A6
bra.s QSRTMV
;
QSCAMV: CKQSst
bsr CHECKMOVENR
bne.s QSRTMV ; error!
move.w #-1,PRDC(A3) ; reduce
bsr INITMOVE
bsr CALCMOVE
bsr EXECMOVE
bsr GETMOVE
moveq #status_OK,D0
QSRTMV:
GETMSGPTR
move.w D0,Qstatus(A1)
move.w PROW(A3),Qrow(A1)
move.w PCOL(A3),Qcol(A1)
;
moveq #RESULT_OK,D0
move.w HWIN(A4),D1
cmp.w HPEV1(A4),D1
bne.s QSRTMVR
moveq #RESULT_WIN,D0
QSRTMVR:
move.w D0,Qresult(A1)
;
moveq #0,D0
move.b MMEV(A6),D0
move.w D0,QmevAM(A1)
move.b HBMEV(A4),D0
move.w D0,QmevPL(A1)
move.b MTK(A6),D0
move.w D0,Qtakes(A1)
bra QSREPLY
;
GETMOVE:
move.l HMV0(A4),A6 ; calculate position according to
moveq #0,D7
move.w MSQ(A6),D7 ; normal board
divu D3,D7
add.w RYLO(A3),D7
subq.w #BRDR,D7
move.w D7,PROW(A3)
swap D7
add.w RXLO(A3),D7
subq.w #BRDR,D7
move.w D7,PCOL(A3)
rts
;
CHECKMOVENR:
GETMSGPTR
move.w Qmovenr(A1),D0
cmp.w HPLYNR(A4),D0
beq.s CHECKMOVENROK
bgt.s CHECKMOVENRERR
move.w D0,-(SP)
bsr EXECBACK
move.w (SP)+,D0
bra.s CHECKMOVENRN
CHECKMOVENRL:
move.w D0,-(SP)
bsr BACKMOVE
move.w (SP)+,D0
CHECKMOVENRN:
cmp.w HPLYNR(A4),D0
blt.s CHECKMOVENRL
CHECKMOVENROK:
moveq #status_OK,D0
rts
CHECKMOVENRERR:
moveq #status_ERROR,D0
rts
;
PTRDOS:
dc.l 0
PTRFILEH:
dc.l 0
DosName:
dc.b "dos.library",0
even
NameTable:
dc.b "Pente:PenteTable",0
even
StringExecTable:
dc.b "Pente:PenteCalcTable",0
even
;
INITOPEN:
move.l PTRDOS(PC),A6
lea NameTable(PC),A0
move.l A0,D1
move.l #MODE_OLD,D2
jsr Open(A6)
lea PTRFILEH(PC),A0
move.l D0,(A0)
rts
;
INITPROG:
move.l ExecBase,A6
lea DosName(PC),A1
moveq #0,D0
jsr OpenLib(A6)
lea PTRDOS(PC),A0
move.l D0,(A0)
beq INITPROGERDOS
;
bsr INITOPEN
bne.s INITPROGREAD
move.l PTRDOS(PC),A6
lea StringExecTable(PC),A0
move.l A0,D1
moveq #0,D2
moveq #0,D3
jsr Execute(A6)
bsr INITOPEN
beq INITPROGERFO
INITPROGREAD:
move.l #LPSN,D0
move.l #MEMF_CLEAR,D1
move.l ExecBase,A6
jsr AllocMem(A6)
move.l D0,A3
beq INITPROGERFO
;
move.l A3,A0
adda.l #PTable,A0
move.l A0,PTableC(A3)
adda.l #TableCLEN,A0
move.l A0,PTableEV(A3)
;
move.l PTRDOS(PC),A6
move.l PTRFILEH(PC),D1
move.l PTableC(A3),D2
move.l #TableLEN,D3
jsr Read(A6)
;
move.l PTRDOS(PC),A6
move.l PTRFILEH(PC),D1
jsr Close(A6)
;
lea PHST(A3),A4
lea PBRD(A3),A5
lea PMVS(A3),A6
;
move.w #BXDIM,PXDIM(A3)
move.w #BYDIM,PYDIM(A3)
move.l #BXMAX,PXMAX(A3)
move.l #BYMAX,PYMAX(A3)
;
move.w #5,PMEVLIM(A3)
moveq #TakeBit,D0
moveq #0,D1
bset D0,D1
move.w D1,PMVAL(A3)
;
lea DPEVPAT(PC),A0
lea PEVPAT(A3),A1
moveq #ESIZE-1,D0
INITPROGPAT:
move.b (A0)+,(A1)+
dbra D0,INITPROGPAT
;
moveq #black,D1 ; black/white indication
swap D1
move.w #white,D1
moveq #0,D2 ; ply count
lea TWGMV(PC),A0 ; WTable pair of bits
move.l A0,D5
lea TBGMV(PC),A0 ; BTable pair of bits
move.l A0,D4
move.l A4,A0
moveq #NPLY-1,D0
INITPROGHSTL:
move.l D1,HcolME(A0)
swap D1
move.w D2,HPLYNR(A0)
move.w #ZWIN,D3
sub.w D2,D3
move.w D3,HWIN(A0)
addq.w #1,D2
move.l D4,HTGMV(A0)
exg D4,D5
lea LHST(A0),A0
dbra D0,INITPROGHSTL
;
lea ZEVesc(PC),A0 ; interface to interrupt-routine
lea RCPMIRQesc(PC),A1
move.l A0,(A1)
;
movem.l PREG0(A3),D0-D7 ; clear data-registers
movem.l A0-A7/D0-D7,PREGS(A3)
moveq #status_OK,D0
rts
;
INITPROGERFO:
bsr ENDPROGDOS
INITPROGERDOS:
moveq #status_ERROR,D0
rts
;
ENDPROG:
ENDPROGPSN:
move.l A3,A1
move.l #LPSN,D0
move.l ExecBase,A6
jsr FreeMem(A6)
ENDPROGDOS:
move.l ExecBase,A6
move.l PTRDOS(PC),A1
jsr CloseLib(A6)
ENDPROGE:
moveq #status_OK,D0
rts
;
CalcPort:
TC_Node_Succ: dc.l 0
TC_Node_Pred: dc.l 0
TC_Node_Type: dc.b NT_MSGPORT
TC_Node_Pri: dc.b 0
TC_Node_Name: dc.l PC_name
TC_Flags: dc.b PA_SIGNAL
TC_sigBit: dc.b 0
TC_SigTask: dc.l 0
TC_lh_Head: dc.l 0
TC_lh_Tail: dc.l 0
TC_lh_TailPred: dc.l 0
TC_lh_Type: dc.b 0
TC_lh_pad: dc.b 0
;
MIRQPort:
TM_Node_Succ: dc.l 0
TM_Node_Pred: dc.l 0
TM_Node_Type: dc.b NT_MSGPORT
TM_Node_Pri: dc.b 0
TM_Node_Name: dc.l PM_name
TM_Flags: dc.b PA_SOFTINT
TM_sigBit: dc.b 0
TM_SigTask: dc.l MIRQinterrupt
TM_lh_Head: dc.l 0
TM_lh_Tail: dc.l 0
TM_lh_TailPred: dc.l 0
TM_lh_Type: dc.b 0
TM_lh_pad: dc.b 0
;
MIRQinterrupt:
TMi_Node_Succ: dc.l 0
TMi_Node_Pred: dc.l 0
TMi_Node_Type: dc.b NT_INTERRUPT
TMi_Node_Pri: dc.b 16
TMi_Node_Name: dc.l 0
TMi_Data: dc.l 0
TMi_Code: dc.l RCPescape
;
DUMMY_MOVE:
move.l A6,HMV0(A4)
move.w #-1,MSQ(A6)
clr.b MMEV(A6)
clr.w MPEV0(A6)
lea LMOV(A6),A6
move.l A6,HMV2(A4)
move.l A6,PGMVS(A3)
rts
;
INITGAME:
movem.l PREGS(A3),A0-A7/D0-D7
move.l A6,PGMVS(A3)
;
move.w #BRDR-1,PXLO1(A3)
move.w #BRDR-1,PYLO1(A3)
move.w PXDIM(A3),PXHI1(A3)
addi.w #BRDR,PXHI1(A3)
move.w PYDIM(A3),PYHI1(A3)
addi.w #BRDR,PYHI1(A3)
move.l PXMAX(A3),D3
lea DIRS(PC),A0 ; fill DIRS
moveq #1,D0
move.w D0,(A0)+
add.w D3,D0
move.w D0,(A0)+
subq.w #1,D0
move.w D0,(A0)+
subq.w #1,D0
move.w D0,(A0)+
moveq #-1,D0
move.w D0,(A0)+
sub.w D3,D0
move.w D0,(A0)+
addq.w #1,D0
move.w D0,(A0)+
addq.w #1,D0
move.w D0,(A0)+
clr.w (A0)
;
bsr INITBRD
move.l PGMVS(A3),A6
bsr DUMMY_MOVE
;
moveq #status_OK,D0
INITGAMEE:
rts
;
INITMOVE:
lea LHST(A4),A4 ; increment A4
tst.w PRDC(A3)
beq.s INITMOVEBA ; skip RDC ?
bsr RDCSIZE ; also determines start RDCboard
bsr INRDC
bra.s INITMOVERDC
INITMOVEBA:
move.w #BRDR,RXLO(A3)
move.w #BRDR,RYLO(A3)
move.w PXDIM(A3),RXDIM(A3)
move.w PYDIM(A3),RYDIM(A3)
bsr BRDADDS
INITMOVERDC:
lea RCPMIRQA4(PC),A0 ; interface to interrupt-routine
move.l A4,(A0)
;
move.l A4,A0 ; fill History with Pointers
move.w #NPLY-1,D7
sub.w HPLYNR(A0),D7 ; Maximum available moves
;
move.l RWEVBRD(A3),D0
move.l RBEVBRD(A3),D1
cmpi.w #white,HcolME(A0)
beq.s INITMOVEHSTL
exg D0,D1
INITMOVEHSTL:
move.l D0,HWEVBRD(A0)
move.l D1,HBEVBRD(A0)
exg D0,D1
lea LHST(A0),A0
dbra D7,INITMOVEHSTL
;
move.l A4,A2 ; initialize recipes
lea ZRCPcode(PC),A0
lea ZRCPSR(PC),A1
moveq #TakeBit,D0
moveq #0,D1
bset D0,D1
lsr.l #1,D1
move.w D1,PESC(A3)
moveq #0,D0
INITMOVESRL:
move.b (A0)+,D0
move.l 0(A1,D0.w),HRCP(A2)
move.l JEVQSmax(A1,D0.w),D1
move.b D1,HTQS(A2)
lea LHST(A2),A2
neg.w PESC(A3)
tst.b D0
bgt.s INITMOVESRL
clr.l HRCP(A2) ; stop-indication for MIRQ
;
move.w HcolME(A4),D4
move.w HcolOP(A4),D5
move.w #ZAEVI,HAEV(A4)
move.w #ZBEVI,HBEV(A4)
move.l RPBRD(A3),A5
move.l HMV0-LHST(A4),A6 ; previous move
rts
;
SOXPEVM: macro
movem.l A0-A4/D0-D6,-(SP)
lea ?1(PC),A4
bsr SOMOV
movem.l (SP)+,A0-A4/D0-D6
endm
;
MRECIPE: macro
move.l HRCP(A4),A0
jsr (A0)
endm
;
CALCMOVE:
moveq #0,D0
MRECIPE
move.l HMV0(A4),A0
move.l HMV2(A4),D6
sub.l A0,D6
lsr.w #3,D6
SOXPEVM SEWPEV
bsr RNDMOVE
rts
;
RNDMOVE:
move.l HMV0(A4),A0 ; search equivalent moves
move.w MPEV(A0),D0
RNDMOVEL:
cmp.w MPEV(A0),D0
bne.s RNDMOVER
lea LMOV(A0),A0
cmpa.l HMV2(A4),A0
bne.s RNDMOVEL
RNDMOVER:
lea RNDSEED(PC),A1 ; update seed
move.w (A1),D1
mulu #141,D1
addi.w #1357,D1
move.w D1,(A1)
move.l A0,D0 ; calculate move
sub.l HMV0(A4),D0
lsr.l #3,D0
mulu D1,D0
swap D0
andi.l #$FFFF,D0
lsl.w #3,D0
move.l HMV0(A4),A0
movem.l (A0),D1-D2
move.l 0(A0,D0.w),(A0)
move.l 4(A0,D0.w),4(A0)
movem.l D1-D2,0(A0,D0.w)
rts
RNDSEED:
dc.w 12345
;
DOMOVE: ; execute entered move, first call INITMOVE
;
move.l PGMVS(A3),HMV0(A4)
cmpi.w #1,HPLYNR(A4) ; check first move
bne.s DOMOVEOK
move.w PYDIM(A3),D0
lsr.w #1,D0
cmp.w PROW(A3),D0
bne DOMOVEERR
move.w PXDIM(A3),D0
lsr.w #1,D0
cmp.w PCOL(A3),D0
bne DOMOVEERR
DOMOVEOK:
move.w PROW(A3),D7 ; calculate position according to
addq.w #BRDR,D7 ; reduced boards
sub.w RYLO(A3),D7
mulu D3,D7
add.w PCOL(A3),D7
addq.w #BRDR,D7
sub.w RXLO(A3),D7
tst.b 0(A5,D7.w)
bne.s DOMOVEERR
;
move.b #EVCall,PTQS(A3)
clr.w HPEV(A4)
move.b MMEV(A6),HBMEV(A4) ; from previous move
move.b HBMEV-LHST(A4),HWMEV(A4)
move.l HMV0(A4),A6
;
move.w REBRD(A3),-(SP) ; adjust end of board
move.w D7,REBRD(A3) ; D7 is generated firstly
bsr GMVS
move.w (SP)+,REBRD(A3) ; restore end of board
;
tst.b D0 ; check WIN
bpl.s DOMOVENOW ; branch when NO WIN
move.w HWIN(A4),D0 ; update MPEV0 with WIN evaluation
move.w D0,MPEV0-LMOV(A6)
DOMOVENOW:
move.l HMV0(A4),A6
move.w MPEV0(A6),MPEV(A6)
lea LMOV(A6),A6
move.l A6,HMV2(A4)
move.l A6,PGMVS(A3)
moveq #status_OK,D0
rts
;
DOMOVEERR:
moveq #status_ERROR,D0
rts
;
EXECMOVE:
tst.w PRDC(A3)
beq.s EXECMOVERDC ; skip RDC ?
bsr INUNRDC
bsr UNRDC
EXECMOVERDC:
move.l HMV0(A4),A6
move.w MPEV0(A6),HPEV0(A4) ; game-history
move.w MPEV(A6),HPEV1(A4) ; game-history
move.w MPEV(A6),MPEV0(A6) ; easy overview only
clr.w MPEV(A6) ; reset MPEV/MTQS
bsr EFMV
lea LMOV(A6),A6 ; A6 points to new move
move.l A6,PGMVS(A3)
rts
;
BACKMOVE:
lea PBRD(A3),A5 ; restore board addresses
adda.l HSBRD(A4),A5
EXECBACK:
move.w HcolME(A4),D4
move.w HcolOP(A4),D5
move.l HMV0(A4),A6
bsr EBMV
move.l A6,PGMVS(A3)
lea -LHST(A4),A4
rts
;
DOEMOVE:
move.w #0,PRDC(A3) ; reduce not
bsr INITMOVE
bsr DOMOVE
cmpi.w #status_OK,D0
bne.s DOEMOVEERR
bsr EXECMOVE
moveq #status_OK,D0
rts
DOEMOVEERR:
tst.w PRDC(A3)
beq.s DOEMOVERDC ; skip RDC ?
bsr INUNRDC
bsr UNRDC
DOEMOVERDC:
move.l HMV0(A4),PGMVS(A3)
lea -LHST(A4),A4
rts
;
INITBRD:
moveq #empsq,D0
move.w D3,D7
mulu D7,D7
subq.w #1,D7
;
lea WHEVBRD(A3),A0
move.w D7,D6
moveq #0,D0
INITBRDLW:
move.b D0,(A0)+
dbra D6,INITBRDLW
;
lea BLEVBRD(A3),A0
move.w D7,D6
INITBRDLB:
move.b D0,(A0)+
dbra D6,INITBRDLB
;
lea PBRD(A3),A0
move.w D7,D6
INITBRDL:
move.b D0,(A0)+
dbra D6,INITBRDL
bsr INITBRDR
;
rts
;
RDCSIZE: ; reduce size of board by 2 rows out of convex hull
; fill arrays PXA and PYA with #1 when stone encountered
movem.l D0-D7/A0,-(SP)
moveq #0,D0
;
move.w PXHI1(A3),D6 ; initialize array PXA
move.b #brdrsq,PXA(A3,D6.w) ; brdrsq<>0
subq.w #1,D6
RDCSIZEX0:
move.b D0,PXA(A3,D6.w)
dbra D6,RDCSIZEX0
move.w PXLO1(A3),D6
move.b #brdrsq,PXA(A3,D6.w)
;
move.w PYHI1(A3),D6 ; initialize array PYA
move.b #brdrsq,PYA(A3,D6.w)
subq.w #1,D6
RDCSIZEY0:
move.b D0,PYA(A3,D6.w)
dbra D6,RDCSIZEY0
move.w PYLO1(A3),D6
move.b #brdrsq,PYA(A3,D6.w)
;
lea PBRD(A3),A0
adda.l D3,A0
adda.l D3,A0
adda.l D3,A0
moveq #BRDR,D5 ; Y-index
move.w PYDIM(A3),D7
subq.w #1,D7
RDCSIZEYL:
move.w PXHI1(A3),D6 ; X-index
subq.w #1,D6
RDCSIZEXL:
tst.b 0(A0,D6.w)
beq.s RDCSIZEXN ; skip empty square
bmi.s RDCSIZEXN ; skip border square
ori.b #1,PXA(A3,D6.w)
ori.b #1,PYA(A3,D5.w)
RDCSIZEXN:
dbra D6,RDCSIZEXL
adda.l D3,A0
addq.w #1,D5
dbra D7,RDCSIZEYL
;
move.w PXHI1(A3),D6 ; determine XHI
lea PXA(A3,D6),A0
RDCSIZEXHIL:
subq.w #1,D6
tst.b -(A0)
beq.s RDCSIZEXHIL
cmp.w PXLO1(A3),D6
bgt.s RDCSIZEXHI2
move.w D3,D6
lsr.w #1,D6
RDCSIZEXHI2:
move.w D6,RXHI2(A3)
addq.w #RBRDR+1,D6
cmp.w PXHI1(A3),D6
ble.s RDCSIZEXHI1
move.w PXHI1(A3),D6
RDCSIZEXHI1:
move.w D6,RXHI1(A3)
subq.w #1,D6
move.w D6,RXHI(A3)
;
moveq #1,D6 ; determine XLO
add.w PXLO1(A3),D6
lea PXA(A3,D6),A0
bra.s RDCSIZEXLON
RDCSIZEXLOL:
addq.w #1,D6
RDCSIZEXLON:
tst.b (A0)+
beq.s RDCSIZEXLOL
cmp.w PXHI1(A3),D6
blt.s RDCSIZEXLO2
move.w D3,D6
lsr.w #1,D6
RDCSIZEXLO2:
move.w D6,RXLO2(A3)
subq.w #RBRDR+1,D6
cmp.w PXLO1(A3),D6
bge.s RDCSIZEXLO1
move.w PXLO1(A3),D6
RDCSIZEXLO1:
move.w D6,RXLO1(A3)
addq.w #1,D6
move.w D6,RXLO(A3)
;
move.w RXHI1(A3),D6
sub.w RXLO(A3),D6
move.w D6,RXDIM(A3)
;
move.w PYHI1(A3),D6 ; determine YHI
lea PYA(A3,D6),A0
RDCSIZEYHIL:
subq.w #1,D6
tst.b -(A0)
beq.s RDCSIZEYHIL
cmp.w PYLO1(A3),D6
bgt.s RDCSIZEYHI2
move.w PYMAX+2(A3),D6
lsr.w #1,D6
RDCSIZEYHI2:
move.w D6,RYHI2(A3)
addq.w #RBRDR+1,D6
cmp.w PYHI1(A3),D6
ble.s RDCSIZEYHI1
move.w PYHI1(A3),D6
RDCSIZEYHI1:
move.w D6,RYHI1(A3)
subq.w #1,D6
move.w D6,RYHI(A3)
;
moveq #1,D6 ; determine YLO
add.w PYLO1(A3),D6
lea PYA(A3,D6),A0
bra.s RDCSIZEYLON
RDCSIZEYLOL:
addq.w #1,D6
RDCSIZEYLON:
tst.b (A0)+
beq.s RDCSIZEYLOL
cmp.w PYHI1(A3),D6
blt.s RDCSIZEYLO2
move.w PYMAX+2(A3),D6
lsr.w #1,D6
RDCSIZEYLO2:
move.w D6,RYLO2(A3)
subq.w #RBRDR+1,D6
cmp.w PYLO1(A3),D6
bge.s RDCSIZEYLO1
move.w PYLO1(A3),D6
RDCSIZEYLO1:
move.w D6,RYLO1(A3)
addq.w #1,D6
move.w D6,RYLO(A3)
;
move.w RYHI1(A3),D6
sub.w RYLO(A3),D6
move.w D6,RYDIM(A3)
;
bsr BRDADDS
moveq #rdcsq,D0
bsr RDC
;
movem.l (SP)+,D0-D7/A0
rts
;
BRDADDS: ; calculate board addresses
;
move.w RYDIM(A3),D0 ; calculate size of reduced boards
subq.w #1,D0
mulu D3,D0
add.w RXDIM(A3),D0
subq.w #1,D0
move.w D0,REBRD(A3)
move.w RYLO(A3),D0 ; calculate begin of boards
mulu D3,D0
add.w RXLO(A3),D0
move.l D0,HSBRD(A4)
lea WHEVBRD(A3),A0
adda.l D0,A0
move.l A0,RWEVBRD(A3)
lea BLEVBRD(A3),A0
adda.l D0,A0
move.l A0,RBEVBRD(A3)
lea PBRD(A3),A0
adda.l D0,A0
move.l A0,RPBRD(A3)
rts
;
BRDRFILL:
move.b D0,(A0)
rts
;
RDC: ; fill reduced border with rdcsq's
moveq #rdcsq,D0
lea BRDRFILL(PC),A6
RDCGO:
movem.l D4-D5,-(SP)
move.l RPBRD(A3),A0
suba.l D3,A0
tst.b -(A0) ; now A0 points to RXLO1,RYLO1
move.w RXDIM(A3),D4
move.w RYDIM(A3),D5
bsr JBRDR
movem.l (SP)+,D4-D5
rts
;
UNRDC: ; fill reduced border with empsq's
moveq #empsq,D0
lea BRDRFILL(PC),A6
bsr RDCGO
INITBRDR:
moveq #brdrsq,D0
lea BRDRFILL(PC),A6
;
movem.l D4-D5,-(SP)
move.w PYLO1(A3),D6
mulu D3,D6
add.w PXLO1(A3),D6
lea PBRD(A3),A0
adda.w D6,A0
move.w PXDIM(A3),D4
move.w PYDIM(A3),D5
bsr JBRDR
movem.l (SP)+,D4-D5
rts
;
INRDCJ: ; Inner reduce subroutine
;
lea -RBRDR(A0),A1
suba.l D3,A1 ; RBRDR times
suba.l D3,A1
moveq #2*RBRDR,D1
INRDCJYL:
moveq #2*RBRDR,D2
INRDCJXL:
tst.b 0(A1,D2.w)
beq.s INRDCJXN ; check empty square
bpl.s INRDCJF ; check stone at square
INRDCJXN:
dbra D2,INRDCJXL
adda.l D3,A1
dbra D1,INRDCJYL
move.b D0,(A0)
INRDCJF:
rts
;
INUNRDCJ: ; Inner unreduce subroutine
;
tst.b (A0)
bpl.s INUNRDCJE ; test empty square or stone
move.b D0,(A0) ; empsq
INUNRDCJE:
rts
;
INUNRDC: ; Inner unreduce
;
moveq #empsq,D0
lea INUNRDCJ(PC),A6
bra.s INRDCGO
;
INRDC: ; Inner reduce
;
moveq #rdcsq,D0
lea INRDCJ(PC),A6
INRDCGO:
movem.l D4-D5,-(SP)
move.l RPBRD(A3),A0
move.w RXDIM(A3),D4
subq.w #2,D4
move.w RYDIM(A3),D5
subq.w #2,D5
move.l A0,-(SP) ; save for next inner rectangle
bsr JBRDR
move.l (SP)+,A0
lea 1(A0,D3.w),A0 ; address of next inner rectangle
subq.w #2,D4
subq.w #2,D5
bsr JBRDR
;
move.w REBRD(A3),D7 ; calculate negative jump values
move.l RPBRD(A3),A5
move.l A5,A0
lea 0(A0,D7.w),A0 ; A0 points to RXHI,RYHI
suba.w RXDIM(A3),A0 ; A0 points to RXLO1,RYHI
;
move.w RYDIM(A3),D2
subq.w #1,D2
INRDCYL:
move.w RXDIM(A3),D1
INRDCXL:
tst.b 0(A0,D1.w)
bpl.s INRDCXN
move.w D7,D6 ; rdcsq found
bra.s INRDCRXN
INRDCRYL:
move.w RXDIM(A3),D1
INRDCRXL:
tst.b 0(A0,D1.w)
bpl.s INRDCRF
INRDCRXN:
subq.w #1,D7
dbra D1,INRDCRXL
;
suba.l D3,A0
addq.w #1,D7 ; D1-loop takes RXDIM+1
add.w RXDIM(A3),D7
sub.w D3,D7
dbra D2,INRDCRYL
INRDCRF:
move.w D7,D0
sub.w D6,D0
move.b D0,0(A5,D6.w)
tst.w D7
bmi.s INRDCE
INRDCXN:
subq.w #1,D7
dbra D1,INRDCXL
;
suba.l D3,A0
addq.w #1,D7 ; D1-loop takes RXDIM+1
add.w RXDIM(A3),D7
sub.w D3,D7
dbra D2,INRDCYL
INRDCE:
movem.l (SP)+,D4-D5
rts
;
JBRDR: ; general subroutine for border
; ; sequence of filling :
; input registers: ; 1 1 -> 1 2
; D3 : PXMAX ; 3 2
; D4 : Xdim ; 3 |
; D5 : Ydim ; | V
; A0 : start-address ; V 2
; A6 : subroutine ; 3 4 4 -> 4
;
move.l A0,-(SP)
move.w D4,D6
JBRDRYLOXL:
jsr (A6)
tst.b (A0)+
dbra D6,JBRDRYLOXL
;
move.w D5,D6
JBRDRXHIYL:
jsr (A6)
adda.l D3,A0
dbra D6,JBRDRXHIYL
;
move.l (SP)+,A0
move.w D5,D6
JBRDRXLOYL:
adda.l D3,A0
jsr (A6)
dbra D6,JBRDRXLOYL
;
move.w D4,D6
tst.b (A0)+
JBRDRYHIXL:
jsr (A6)
tst.b (A0)+
dbra D6,JBRDRYHIXL
rts
;
MWR: macro ; parameters label_empty,label_stop/border,label_black
add.w D0,D6
move.b 0(A5,D6.w),D2
beq ?1
bmi ?2
cmp.b D4,D2
bne ?3
endm
;
MWRE: macro ; parameters label_empty/border,label_black
add.w D0,D6
move.b 0(A5,D6.w),D2
ble ?1
cmp.b D4,D2
bne ?2
endm
;
MWRW: macro ; parameter label_stop
add.w D0,D6
cmp.b 0(A5,D6.w),D4
bne ?1
endm
;
MWRB: macro ; parameter label_stop
add.w D0,D6
cmp.b 0(A5,D6.w),D5
bne ?1
endm
;
MWL: macro ; parameters label_empty,label_stop/border,label_black
sub.w D0,D6
move.b 0(A5,D6.w),D2
beq ?1
bmi ?2
cmp.b D4,D2
bne ?3
endm
;
MWLE: macro ; parameters label_empty/border,label_black
sub.w D0,D6
move.b 0(A5,D6.w),D2
ble ?1
cmp.b D4,D2
bne ?2
endm
;
MWLW: macro ; parameter label_stop
sub.w D0,D6
cmp.b 0(A5,D6.w),D4
bne ?1
endm
;
MWLB: macro ; parameter label_stop
sub.w D0,D6
cmp.b 0(A5,D6.w),D5
bne ?1
endm
;
QS_WIN: macro
moveq #-1,D0
rts
endm
;
QS_tkr: macro ; parameter label_stop
addq.b #1,MMEV(A6)
add.w D3,MPEV0(A6)
bset D1,MTK(A6)
ori.b #EVCtkr,MTQS(A6)
bra ?1
endm
;
QS_tkl: macro ; parameter label_stop
addq.b #1,MMEV(A6)
add.w D3,MPEV0(A6)
subq.w #4,D1
bset D1,MTK(A6)
addq.w #4,D1
ori.b #EVCtkl,MTQS(A6)
bra ?1
endm
;
QS_5t: macro ; parameter label_stop
ori.b #EVC5t,MTQS(A6)
bra ?1
endm
;
QS_5dt: macro ; parameter label_stop
ori.b #EVC5t,MTQS(A6)
bra ?1
endm
;
QS_5s: macro ; parameter label_stop
ori.b #EVC5s,MTQS(A6)
bra ?1
endm
;
QS_tkt: macro ; parameter label_stop
ori.b #EVCtkt,MTQS(A6)
bra ?1
endm
;
QS_tks: macro ; parameter label_stop
ori.b #EVCtks,MTQS(A6)
bra ?1
endm
;
QSstart:
; D0 : direction increment
; D1 : direction bit
; D2 : temporary square contents
; D3 : positional evaluation bonus
; D4 : player's color
; D5 : opponent's color
; D6 : temporary square
; D7 : square of move
;
move.w D7,D6
rQS____: MWR rQSe___, l____QS, rQSb___
rQSw___: MWR rQSwe__, l____QSw, l____QSw
rQSww__: MWR rQSwwe_, l____QSww, rQSwwb
rQSwww_: MWR rQSwwwe, l____QSwww, l____QSwww
rQSwwww: QS_WIN
;
rQSe___: MWRW l____QSe
rQSew__: MWRW l____QSew
rQSeww_: MWRW l____QSeww
rQSewww: QS_5t l____QS
;
rQSb___: MWRB l____QSb
rQSbb__: MWR rQSbbe, l____QSbb, rQSbbb_
rQSbbw: QS_tkr l____QSbb
;
rQSbbe: QS_tkt l____QSbb
;
rQSbbb_: MWRB l____QSbbb
rQSbbbb: QS_5s l____QS
;
rQSwe__: MWRW l____QSwe
rQSwew_: MWRW l____QSwew
rQSweww: QS_5t l____QSw
;
rQSwwe_: MWRW l____QSwwe
rQSwwew: QS_5t l____QSww
;
rQSwwb: QS_tks l____QSww
;
rQSwwwe: QS_5t l____QSwww
;
l____QS: move.w D7,D6
MWL l___eQS, QSend, l___bQS
l___wQS: MWL l__ewQS, QSend, QSend
l__wwQS: MWL l_ewwQS, QSend, lbwwQS
l_wwwQS: MWL lewwwQS, QSend, QSend
lwwwwQS: QS_WIN
;
l___bQS: MWLB QSend
l__bbQS: MWL lebbQS, QSend, l_bbbQS
l_wbbQS: QS_tkl QSend
;
l_bbbQS: MWLB QSend
lbbbbQS: QS_5s QSend
;
lebbQS: QS_tkt QSend
;
lbwwQS: QS_tks QSend
;
l____QSw: move.w D7,D6
MWL l___eQSw, QSend, l___bQS
l___wQSw: MWL l__ewQSw, QSend, QSend
l__wwQSw: MWL lewwQSw, QSend, lbwwQS
lwwwQSw: QS_WIN
;
l___eQS: MWLW QSend
l__ewQS:
l__weQS:
l___eQSw: MWLW QSend
l_ewwQS:
l_wewQS:
l_wweQS:
l__ewQSw:
l__weQSw:
l___eQSww: MWLW QSend
lewwwQS:
lwwweQS:
lwwwQSe:
lewwQSw:
lwewQSw:
lwweQSw:
lewQSww:
lwwQSew:
lwwQSwe:
leQSwww:
lwQSwwe:
lwQSwew:
lwQSeww: QS_5t QSend
;
l____QSe: move.w D7,D6
MWL l___eQS, QSend, l___bQS
l___wQSe: MWL l__ewQS, QSend, QSend
l__wwQSe: MWL l_ewwQS, QSend, lbwwQS
l_wwwQSe: QS_5t l_wwwQS
;
l____QSww: move.w D7,D6
MWL l___eQSww, QSend, l___bQS
l___wQSww: MWL lewQSww, QSend, QSend
lwwQSww: QS_WIN
;
l____QSwe: move.w D7,D6
MWL l___eQSw, QSend, l___bQS
l___wQSwe: MWL l__ewQSw, QSend, QSend
l__wwQSwe: QS_5t l__wwQSw
;
l____QSew: move.w D7,D6
MWL l___eQS, QSend, l___bQS
l___wQSew: MWL l__ewQS, QSend, QSend
l__wwQSew: QS_5t l__wwQS
;
l____QSwww: move.w D7,D6
MWL leQSwww, QSend, l___bQS
lwQSwww: QS_WIN
;
l____QSwwe: move.w D7,D6
MWL l___eQS, QSend, l___bQS
l___wQSwwe: QS_5t l___wQSww
;
l____QSwew: move.w D7,D6
MWL l___eQSw, QSend, l___bQS
l___wQSwew: QS_5t l___wQSw
;
l____QSeww: move.w D7,D6
MWL l___eQS, QSend, l___bQS
l___wQSeww: QS_5t l___wQS
;
l____QSb: move.w D7,D6
MWL l___eQS, QSend, l___bQSb
l___wQSb: bra l___wQS
;
l___bQSb: MWLB QSend
l__bbQSb: MWL lebbQS, QSend, lbbbQSb
lwbbQSb: QS_tkl QSend
;
lbQSbbb:
lbbQSbb:
lbbbQSb: QS_5s QSend
;
l____QSbb: move.w D7,D6
MWL l___eQS, QSend, l___bQSbb
l___wQSbb: bra l___wQS
;
l___bQSbb: MWLB QSend
l__bbQSbb: QS_5s l__bbQS
;
l____QSbbb: move.w D7,D6
MWL l___eQS, QSend, l___bQSbbb
l___wQSbbb: bra l___wQS
;
l___bQSbbb: QS_5s l___bQS
;
QSend: moveq #0,D0
rts
;
GQS: ; generate takes and threats
; D0 : scratch, return 0=noWIN, -1=WIN
; D1 : scratch
; D2 : temporary, original value destroyed
; D3 : original value restored
; D4 : my color
; D5 : opponent color
;
move.l D3,-(SP)
clr.b PIQS(A3) ; clear integral QS-code
move.w PMVAL(A3),D3
move.w REBRD(A3),D7
GQSL:
move.b 0(A5,D7.w),D0
beq.s GQSM
bpl.s GQSN
ext.w D0
add.w D0,D7
bpl.s GQSL
bmi.s GQSEL
GQSM:
move.w D7,MSQ(A6)
move.w HPEV(A4),MPEV0(A6)
move.b HWMEV(A4),MMEV(A6)
;
move.b #EVCn,MTQS(A6) ; indicates normal move
moveq #4,D1
clr.b MTK(A6)
lea DIRS+8(PC),A0
move.w (A0)+,D0
GQSML:
bsr QSstart
bmi.s QQWIN
addq.w #1,D1
move.w (A0)+,D0
bne.s GQSML
;
move.b MTQS(A6),D0 ; pattern of realised move
and.b PTQS(A3),D0 ; pattern of allowed moves
beq.s GQSN
or.b D0,PIQS(A3) ; add possibly EVC5s-code
move.b MMEV(A6),D0
cmp.b PMEVLIM+1(A3),D0
bge.s QQWIN
GQSC:
lea LMOV(A6),A6
GQSN:
dbra D7,GQSL
GQSEL:
move.l (SP)+,D3
moveq #0,D0
rts
;
QQWIN: lea LMOV(A6),A6
move.l (SP)+,D3
moveq #-1,D0
rts
; white-code black-code
dc.w %0000000000000000,%0000000000000000 ; - 80, $00
dc.w %0000000000000000,%0000000000000000 ; - 76, $04
dc.w %0000000000000000,%0000000000000000 ; - 72, $08
dc.w %0000000000000000,%0000000000000000 ; - 68, $0C
dc.w %0000000000000000,%0000000000000000 ; - 64, $10
dc.w %0000000000000000,%0000000000000000 ; - 60, $14
dc.w %0000000000000000,%0000000000000000 ; - 56, $18
dc.w %0000000000000000,%0000000000000000 ; - 52, $1C
dc.w 0,0,0,0,0,0,0,0 ; - 48, $20
dc.w %0000000001000000,%0000000010000000 ; - 32, $30
dc.w %0000000010000000,%0000000001000000 ; - 28, $34
dc.w %0000000000010000,%0000000000100000 ; - 24, $38
dc.w %0000000000100000,%0000000000010000 ; - 20, $3C
dc.w %0000000000000100,%0000000000001000 ; - 16, $40
dc.w %0000000000001000,%0000000000000100 ; - 12, $44
dc.w %0000000000000001,%0000000000000010 ; - 8, $48
dc.w %0000000000000010,%0000000000000001 ; - 4, $4C
TWGMV: dc.w %0000000000000000 ; + 0, $50
TBGMV: dc.w %0000000000000000 ; + 2, $02
dc.w %0000000000000000,%0000000000000000 ; + 4, $04
dc.w %0000000000000000,%0000000000000000 ; + 8, $08
dc.w %0000000000000000,%0000000000000000 ; + 12, $0C
dc.w %0000000000000000,%0000000000000000 ; + 16, $10
dc.w %0000000000000000,%0000000000000000 ; + 20, $14
dc.w %0000000000000000,%0000000000000000 ; + 24, $18
dc.w %0000000000000000,%0000000000000000 ; + 28, $1C
dc.w 0,0,0,0,0,0,0,0 ; + 32, $20
dc.w %0000000100000000,%0000001000000000 ; + 48, $30
dc.w %0000001000000000,%0000000100000000 ; + 52, $34
dc.w %0000010000000000,%0000100000000000 ; + 56, $38
dc.w %0000100000000000,%0000010000000000 ; + 60, $3C
dc.w %0001000000000000,%0010000000000000 ; + 64, $40
dc.w %0010000000000000,%0001000000000000 ; + 68, $44
dc.w %0100000000000000,%1000000000000000 ; + 72, $48
dc.w %1000000000000000,%0100000000000000 ; + 76, $4C
;
MGMVR: macro ; parameter end-code,displacement
add.w D0,D6
move.b 0(A5,D6.w),D2
bpl.s MGMVR?0
ori.w #?1,D3
bra.s GMVLT
MGMVR?0:
or.w ?2(A0,D2.w),D3
endm
;
MGMVL: macro ; parameter end-code,displacement
sub.w D0,D6
move.b 0(A5,D6.w),D2
bpl.s MGMVL?0
ori.w #?1,D3
bra.s GMVE
MGMVL?0:
or.w ?2(A0,D2.w),D3
endm
;
GMVS:
; assumption : A3 : PSN
; A4 : HST, PGMV
; A5 : BRD
; A6 : MOVS
; D7 : stone square
; usage A0 : DIRS
; A1 : WEVBRD, TableC
; A2 : BEVBRD, TableEV
; D0 : scratch, return 0=noWIN, 1=WIN
; D1 : scratch
; D4 : MY color
; D5 : OPPONENT color
;
move.l D3,-(SP) ; high-byte = 0
clr.b PIQS(A3) ; clear integral QS-code
move.w REBRD(A3),D7
GMVSL:
move.b 0(A5,D7.w),D0
beq.s GMVSM
bpl GMVSN
ext.w D0
add.w D0,D7
bpl.s GMVSL
bmi GMVSEL
GMVSM:
move.w D7,MSQ(A6)
move.b #EVCn,MTQS(A6)
clr.b MTK(A6)
move.b HWMEV(A4),MMEV(A6)
;
movem.l HWEVBRD(A4),A1/A2 ; HWEVBRD/HBEVBRD
move.w HPEV(A4),D2
moveq #0,D3
move.b 0(A1,D7.w),D3
add.w D3,D2
move.b 0(A2,D7.w),D3
add.w D3,D2
move.w D2,MPEV0(A6)
;
move.l HTGMV(A4),A0 ; TXGMV
movem.l PTableC(A3),A1/A2 ; TableC/TableEV
move.l A4,-(SP)
;
moveq #0,D2 ; temp. neighbour
; note high-byte(D2)==0!!!
moveq #4,D1 ; direction-index
lea DIRS+8(PC),A4
move.w (A4)+,D0
GMVL:
GMVRT:
moveq #0,D3 ; build neighbour-pattern
move.w D7,D6
MGMVR %0000000011111111, -80
MGMVR %0000000000111111, -72
MGMVR %0000000000001111, -64
MGMVR %0000000000000011, -56
GMVLT:
move.w D7,D6
MGMVL %1111111100000000, 0
MGMVL %1111110000000000, 8
MGMVL %1111000000000000, 16
MGMVL %1100000000000000, 24
GMVE:
move.b 0(A1,D3.l),D2
bmi.s GMVSW
or.b D2,MTQS(A6)
GMVtkr:
lsr.b #1,D2
bcc.s GMVtkl
bset D1,MTK(A6)
addq.b #1,MMEV(A6)
GMVtkl:
lsr.b #1,D2
bcc.s GMVEV
subq.b #4,D1
bset D1,MTK(A6)
addq.b #4,D1
addq.b #1,MMEV(A6)
GMVEV:
add.l D3,D3
move.w 0(A2,D3.l),D3
add.w D3,MPEV0(A6)
GMVN:
addq.w #1,D1
move.w (A4)+,D0
bne GMVL
;
move.l (SP)+,A4 ; restore A4
move.b PTQS(A3),D0 ; pattern of allowed moves
and.b MTQS(A6),D0 ; pattern of realised move
beq.s GMVSN
;
or.b D0,PIQS(A3) ; add possibly EVC5s-code
move.b MMEV(A6),D0
cmp.b PMEVLIM+1(A3),D0
bge.s GMVSWM
;
lea LMOV(A6),A6
GMVSN:
dbra D7,GMVSL
GMVSEL:
move.l (SP)+,D3
moveq #0,D0
rts
;
GMVSW: move.l (SP)+,A4 ; restore A4
GMVSWM: lea LMOV(A6),A6
move.l (SP)+,D3
moveq #-1,D0
rts
;
; adjust PEV boards by additions
;
EBBEVBRD:
move.l HBEVBRD(A4),A1
lea -BRDR(A1,D6.w),A1
bra.s EBBEVBRDFW
EFWEVBRD:
move.l HWEVBRD(A4),A1
lea -BRDR(A1,D7.w),A1
EBBEVBRDFW:
suba.l D3,A1
suba.l D3,A1
suba.l D3,A1
lea PEVPAT(A3),A2
moveq #0,D2
moveq #2*BRDR,D1
EFWEVBRDL1:
moveq #2*BRDR,D0
EFWEVBRDL0:
move.b (A2)+,D2
add.b D2,0(A1,D0.w)
dbra D0,EFWEVBRDL0
adda.l D3,A1
dbra D1,EFWEVBRDL1
rts
;
; adjust PEV boards by subtractions
;
EFBEVBRD:
move.l HBEVBRD(A4),A1
lea -BRDR(A1,D6.w),A1
bra.s EFBEVBRDBW
EBWEVBRD:
move.l HWEVBRD(A4),A1
lea -BRDR(A1,D7.w),A1
EFBEVBRDBW:
suba.l D3,A1
suba.l D3,A1
suba.l D3,A1
lea PEVPAT(A3),A2
moveq #0,D2
moveq #2*BRDR,D1
EFBEVBRDL1:
moveq #2*BRDR,D0
EFBEVBRDL0:
move.b (A2)+,D2
sub.b D2,0(A1,D0.w)
dbra D0,EFBEVBRDL0
adda.l D3,A1
dbra D1,EFBEVBRDL1
rts
;
EFMV: ; Execute Forward Move
;
move.w MSQ(A6),D7
move.b D4,0(A5,D7.w)
bsr EFWEVBRD
move.b MTK(A6),D1
beq.s EFMVE
;
lea DIRS-2(PC),A0
EFMVL:
tst.w (A0)+
lsr.b #1,D1
bcc.s EFMVL
move.b D1,-(SP)
move.w D7,D6
add.w (A0),D6
move.b #empsq,0(A5,D6.w)
bsr EFBEVBRD
add.w (A0),D6
move.b #empsq,0(A5,D6.w)
bsr EFBEVBRD
move.b (SP)+,D1
bne.s EFMVL
EFMVE:
rts
;
EBMV: ; Execute Backward Move
;
move.w MSQ(A6),D7
move.b #empsq,0(A5,D7.w)
bsr EBWEVBRD
move.b MTK(A6),D1
beq.s EBMVE
;
lea DIRS-2(PC),A0
EBMVL:
tst.w (A0)+
lsr.b #1,D1
bcc.s EBMVL
move.b D1,-(SP)
move.w D7,D6
add.w (A0),D6
move.b D5,0(A5,D6.w)
bsr EBBEVBRD
add.w (A0),D6
move.b D5,0(A5,D6.w)
bsr EBBEVBRD
move.b (SP)+,D1
bne.s EBMVL
EBMVE:
rts
;
EFQS: ; Execute Forward Quiescense Search
;
move.w MSQ(A6),D7
move.b D4,0(A5,D7.w)
move.b MTK(A6),D1
beq.s EFQSE
;
lea DIRS(PC),A0
EFQSL:
move.w (A0)+,D0
lsr.b #1,D1
bcc.s EFQSL
move.w D7,D6
add.w D0,D6
move.b #empsq,0(A5,D6.w)
add.w D0,D6
move.b #empsq,0(A5,D6.w)
tst.b D1
bne.s EFQSL
EFQSE: rts
;
EBQS: ; Execute Backward Quiescense Search
;
move.w MSQ(A6),D7
move.b #empsq,0(A5,D7.w)
move.b MTK(A6),D1
beq.s EBQSE
;
lea DIRS(PC),A0
EBQSL:
move.w (A0)+,D0
lsr.b #1,D1
bcc.s EBQSL
move.w D7,D6
add.w D0,D6
move.b D5,0(A5,D6.w)
add.w D0,D6
move.b D5,0(A5,D6.w)
tst.b D1
bne.s EBQSL
EBQSE: rts
;
SEYWMOV: macro
; D0.w EV* to be searched for
; D1.w MAXrecNR, ALSO output-recnr
; A0.l STARTrecAD
;
; v(D3) >= v(D2) >= v(D1)
;
move.w D1,D4
subq.w #1,D4
asl.w #3,D4 ; * 8=LMOV
cmp.w ?1(A0,D4.w),D0
ble.s SEYWMOVE?0 ; D0 <= v(LASTrec)
;
if ?1=0
cmp.w (A0),D0
else
cmp.w ?1(A0),D0
endif
blt.s SEYWMOVL?0
clr.w D1
bra.s SEYWMOVE?0 ; D0 >= v(FIRSTrec)
SEYWMOVL?0:
clr.w D3
SEYWMOVL1?0:
move.w D1,D2
SEYWMOVL2?0:
add.w D3,D2
asr.w #1,D2
cmp.w D3,D2
beq.s SEYWMOVE?0
move.w D2,D4
asl.w #3,D4 ; * 8=LMOV
cmp.w ?1(A0,D4.w),D0
beq.s SEYWMOV2?0
bgt.s SEYWMOVLT?0
move.w D2,D3 ; v(D2) > D0
bra.s SEYWMOVL1?0
SEYWMOVLT?0:
move.w D2,D1 ; D0 > v(D2)
bra.s SEYWMOVL2?0
SEYWMOV2?0:
move.w D2,D1
addq.w #1,D1
SEYWMOVE?0:
endm
;
SEWPEV0:
move.w (A1),D0 ; MPEV0 of White move
SEYWMOV MPEV0
rts
;
SEWPEV:
move.w MPEV(A1),D0 ; MPEV of White move
SEYWMOV MPEV
rts
;
SEYBMOV: macro
; D0.w EV* to be searched for
; D1.w MAXrecNR, ALSO output-recnr
; A0.l STARTrecAD
;
; v(D3) <= v(D2) <= v(D1)
;
move.w D1,D4
subq.w #1,D4
asl.w #3,D4 ; * 8=LMOV
cmp.w ?1(A0,D4.w),D0
bge.s SEYBMOVE?0 ; D0 >= v(LASTrec)
;
if ?1=0
cmp.w (A0),D0
else
cmp.w ?1(A0),D0
endif
bgt.s SEYBMOVL?0
clr.w D1
bra.s SEYBMOVE?0 ; D0 <= v(FIRSTrec)
SEYBMOVL?0:
clr.w D3
SEYBMOVL1?0:
move.w D1,D2
SEYBMOVL2?0:
add.w D3,D2
asr.w #1,D2
cmp.w D3,D2
beq.s SEYBMOVE?0
move.w D2,D4
asl.w #3,D4 ; * 8=LMOV
cmp.w ?1(A0,D4.w),D0
beq.s SEYBMOV2?0
blt.s SEYBMOVLT?0
move.w D2,D3 ; v(D2) < D0
bra.s SEYBMOVL1?0
SEYBMOVLT?0:
move.w D2,D1 ; D0 < v(D2)
bra.s SEYBMOVL2?0
SEYBMOV2?0:
move.w D2,D1
addq.w #1,D1
SEYBMOVE?0:
endm
;
SEBPEV0:
move.w (A1),D0 ; MPEV0 of Black move
SEYBMOV MPEV0
rts
;
SEBPEV:
move.w MPEV(A1),D0 ; MPEV of Black move
SEYBMOV MPEV
rts
;
SOMOV:
; Sort moves
; D6.w MAXrecNR
; A0.l STARTrecAD
; A4.l SUBROUTINE-AD
;
; D0-D6 : temp. use
; |A0 | | | |A1 | | | ... |#D6
; |A0 | | | |A2 |A3 |-----
; #D1 #D5 (D0)
;
cmpi.w #1,D6
ble.s SOMOVE
subq.w #2,D6
move.l A0,A1
clr.w D5
SOMOVL: lea LMOV(A1),A1
addq.w #1,D5
move.w D5,D1
jsr (A4)
move.w D5,D4
sub.w D1,D4
beq.s SOMOVN
subq.w #1,D4
move.l A1,A2
;
movem.l D0-D1,-(SP) ; save original D0-D1
movem.l (A2)+,D0-D1 ; save 8 bytes
movem.l D0-D1,-(SP) ; at (SP)
;
SOMOVR: movem.l -16(A2),D0-D1 ; get previous 8 bytes, order D0->D1
movem.l D0-D1,-(A2) ; copy in order D1-D0, decr A2 by 8 bytes
dbra D4,SOMOVR
;
movem.l (SP)+,D0-D1 ; now copy intended 8 bytes
movem.l D0-D1,-(A2) ; to destination
movem.l (SP)+,D0-D1 ; restore original D0-D1
;
SOMOVN: dbra D6,SOMOVL
SOMOVE: rts
;
MIQS: macro ; check pente solve/threat
btst #EVCbit5t,PMTQS(A3)
bne.s MIQSE?0 ; branch when already pente threat
btst #EVCbit5s,PIQS(A3)
beq.s MIQSE?0 ; branch when NO pente solve
move.l HMV0(A4),A0 ; now start filtering
move.l A0,A6
MIQSL?0:
move.b MTQS(A0),D0
andi.b #EVCs5t,D0
beq.s MIQSN?0
move.l (A0),(A6)+ ; copy pente solving move
move.l 4(A0),(A6)+
MIQSN?0:
lea LMOV(A0),A0
cmpa.l HMV2(A4),A0
bne.s MIQSL?0
move.l A6,PGMVS(A3)
move.l A6,HMV2(A4)
MIQSE?0:
endm
;
ZEV: ; White/Black Evaluation
; assumption :
; A4 : pointer to HST
; A6 : pointer to MOVE
; D0 : return-value = PEV
;
move.w D0,HPEV(A4)
move.b HTQS(A4),PTQS(A3)
move.b MTQS(A6),D0
move.b D0,PMTQS(A3)
btst #EVCbit5t,D0
beq.s ZEVno_t
andi.b #EVCs5t,PTQS(A3)
ZEVno_t:
move.b MMEV(A6),HBMEV(A4)
move.b HBMEV-LHST(A4),HWMEV(A4)
move.l PGMVS(A3),A6
move.l A6,HMV0(A4)
bsr GMVS
move.l A6,PGMVS(A3)
move.l A6,HMV2(A4)
cmpa.l HMV0(A4),A6
beq ZEVnoMV
tst.b D0
bmi ZEVWIN
;
MIQS
move.l HMV0(A4),A0
move.l A6,D6
sub.l A0,D6
lsr.w #3,D6
SOXPEVM SEWPEV0
ZEVS:
move.w #ZCEVI,HCEV(A4)
move.l HMV0(A4),A6
ZEVL: move.l A6,HMV1(A4)
bsr EFMV
movem.l D4-D5/A4/A6,-(SP)
lea LHST(A4),A4
move.w HcolME(A4),D4
move.w HcolOP(A4),D5
ZEVNHST:
move.w HAEV-LHST(A4),D0
neg.w D0
move.w D0,HBEV(A4)
move.w HBEV-LHST(A4),D0
neg.w D0
move.w D0,HAEV(A4)
move.w MPEV0(A6),D0
neg.w D0
MRECIPE
movem.l (SP)+,D4-D5/A4/A6
neg.w D0
move.w D0,MPEV(A6)
bsr EBMV
ZEVTEV:
move.w MPEV(A6),D0
cmp.w HCEV(A4),D0 ; HCEV <= HAEV <= HBEV
ble.s ZEVN ; D0 <= HCEV ?
move.w D0,HCEV(A4)
cmp.w HAEV(A4),D0 ; test current-ev
ble.s ZEVN ; D0 <= HAEV ?
move.w D0,HAEV(A4)
cmp.w HBEV(A4),D0 ; test beta-window
bge.s ZEVEF ; D0 >= HBEV ?
ZEVN: lea LMOV(A6),A6
cmpa.l HMV2(A4),A6
bne ZEVL
ZEVE: move.w HCEV(A4),D0
move.l HMV0(A4),PGMVS(A3)
rts
ZEVEF:
addi.w #ZBEV,D0 ; avoid false ties
move.l HMV0(A4),PGMVS(A3)
rts
;
ZEVWIN:
move.w HWIN(A4),D0
move.l HMV0(A4),A0
move.w D0,(A0)+ ; D0 --> MPEV0
move.w D0,(A0)+ ; D0 --> MPEV
move.l 4-LMOV(A6),(A0)+ ; copy rest
move.l A0,HMV2(A4)
move.l HMV0(A4),PGMVS(A3)
rts
ZQSWIN:
move.w HWIN(A4),D0
move.w D0,MPEV0-LMOV(A6)
move.w D0,MPEV-LMOV(A6)
move.l A6,HMV2(A4)
move.l HMV0(A4),PGMVS(A3)
rts
ZEVnoMV:
ZQSnoMV:
move.w HPEV(A4),D0
rts
ZEVesc:
ZQSesc: add.w PESC(A3),D0
rts
;
ZQS: ; Z Quiescense Search
; assumption :
; A4 : pointer to HST
; A6 : pointer to MOVE
; D0 : return-value = PEV
;
move.w D0,HPEV(A4)
move.b HTQS(A4),PTQS(A3)
move.b MTQS(A6),D0
move.b D0,PMTQS(A3)
btst #EVCbit5t,D0
beq.s ZQSno_t
andi.b #EVCs5t,PTQS(A3)
ZQSno_t:
move.b MMEV(A6),HBMEV(A4)
move.b HBMEV-LHST(A4),HWMEV(A4)
move.l PGMVS(A3),A6
move.l A6,HMV0(A4)
bsr GQS
move.l A6,PGMVS(A3)
move.l A6,HMV2(A4)
cmpa.l HMV0(A4),A6
beq.s ZQSnoMV
tst.b D0
bmi.s ZQSWIN
;
MIQS
move.w #ZCEVI,HCEV(A4)
btst #EVCbitn,PTQS(A3) ; check normal moves generation
bne.s ZQSEVI
move.b PMTQS(A3),D0 ; check previous move's threats
andi.b #EVCQSI,D0
bne.s ZQSEVI
move.w HPEV(A4),HCEV(A4)
ZQSEVI:
move.l HMV0(A4),A6
ZQSL: move.l A6,HMV1(A4)
bsr EFQS
movem.l D4-D5/A4/A6,-(SP)
lea LHST(A4),A4
move.w HcolME(A4),D4
move.w HcolOP(A4),D5
move.w HAEV-LHST(A4),D0 ; negate ALFA
neg.w D0
move.w D0,HBEV(A4)
move.w HBEV-LHST(A4),D0 ; negate BETA
neg.w D0
move.w D0,HAEV(A4)
move.w MPEV0(A6),D0
neg.w D0
MRECIPE
movem.l (SP)+,D4-D5/A4/A6
neg.w D0 ; negate return-value
move.w D0,MPEV(A6)
bsr EBQS
ZQSTEV:
move.w MPEV(A6),D0
cmp.w HCEV(A4),D0 ; HAEV <= HBEV <= HCEV
ble.s ZQSN ; D0 <= HCEV ?
move.w D0,HCEV(A4)
cmp.w HAEV(A4),D0 ; test current-ev
ble.s ZQSN ; D0 <= HAEV ?
move.w D0,HAEV(A4)
cmp.w HBEV(A4),D0 ; test beta-window
bge.s ZQSEF ; D0 >= HBEV ?
ZQSN: lea LMOV(A6),A6
cmpa.l HMV2(A4),A6
bne ZQSL
ZQSE: move.w HCEV(A4),D0
move.l HMV0(A4),PGMVS(A3)
rts
ZQSEF:
addi.w #ZBEV,D0 ; avoid false ties
move.l HMV0(A4),PGMVS(A3)
rts
end